<?php
/**
 * TODO писать в кэш статиску по кол-ву тендеров в регионе, типе. Затем её можно
 * будет легко и просто выводить где угодно
 */

/**
 * модель данных для поиска, кэширование
 * singleton
 */
class multitender_model_data_common extends multitender_model {
    /**
     * Get array data
     * @param string $name
     * @return array
     */
    public function get_raw($name = null) {
        if (empty($name)) {
            return $this->data;
        } else {
            return $this->data[$name];
        }
    }

    public function get_data() {
        return $this->data;
    }

    private static $instance;
    private static $canInstanciate = false;

    private $data = array();

    // this be private by normal!
    public function __construct() {
        if (!self::$canInstanciate) {
            trigger_error('Unable to instantiate, this is singleton, run ass CLASS::singleton', E_USER_ERROR);
        }
        parent::__construct();
        $this->init();
    }

    /**
     * Instantiate method
     * @return multitender_model_data_common
     */
    public static function singleton() {
        if (!isset(self::$instance)) {
            self::$canInstanciate = true;
            self::$instance = new self;
            self::$canInstanciate = false;
        }
        return self::$instance;
    }

    public function __clone() {
        trigger_error('Clone is not allowed.', E_USER_ERROR);
    }

    private function init() {
        $md5_key = md5($_SERVER['SERVER_NAME'].__FILE__.'data');

        if ($this->memcache_obj) {
            $this->data = $this->memcache_obj->get($md5_key);
        }

        if (empty($this->data)) {
            $this->_get_from_db();
            $this->_gen_all();

            if ($this->memcache_obj) {
                 // TODO обвертка для мемкэша, добавить разнос именно там
                if( ! $this->memcache_obj->replace($md5_key, $this->data, 0,  $this->mt_rand()) ) {
                    $this->memcache_obj->set($md5_key, $this->data, 0, $this->mt_rand());
                }
            }
        }

        if (empty($this->data)) {
            exit('FATAL, no data');
        }
    }

    private function mt_rand() {
        $time = 60*60;
        return mt_rand(0.9*$time, 1.1*$time);
    }

    private function _get_from_db() {
        $what = array('okrug', 'region', 'type', 'rubric');

        foreach ( $what as $w ) {
            $array = $this->db->GetArray("SELECT * FROM $w ORDER BY name");
            $this->data[$w] = $this->_clear_mysql_array($array);
        }
    }

    private function _gen_all() {
        $this->_gen_type_parent();
        $this->_gen_okrug_region();

    }

    /**
     * use in model/search
     */
    private function _gen_type_parent() {
        $return = array();
        foreach($this->data['type'] as $top_id => $top_value) {
            $return[$top_id] = array();
            foreach($this->data['type'] as $p_id => $p_value) {
                if ($top_id == $p_value['parent_id']) {
                    $return[$top_id][] = $p_id;
                }
            }
        }
        $this->data['type_parent'] = $return;
    }

    /**
     * use in model/search
     */
    private function _gen_okrug_region() {
        $return = array();
        foreach($this->data['okrug'] as $okrug_id => $okrug_value) {
           $return[$okrug_id] = array();
            foreach($this->data['region'] as $region_id => $region_value) {
                if ($okrug_id == $region_value['okrug_id']) {
                    $return[$okrug_id][] = $region_id;
                }
            }
        }
        $this->data['okrug_region'] = $return;
    }

    /**
     * key must int
     * @param array $array
     * @param <type> $key
     */
    private function _clear_mysql_array(array $array, $key='id') {
        $return = array();
        foreach ($array as $one) {
            $id = (int) $one[$key];
            $return[$id] = array();
            foreach ($one as $k => $v) {
                // clear numeric keys
                if ( is_numeric($k) ) {
                    continue;
                }
                $return[$id][trim($k)] = trim($v);
            }
        }
        return $return;
    }

}
